package com.mulanweb.api.module.controller.event;

import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.mulanweb.api.module.controller.BaseController;
import com.mulanweb.api.module.model.*;
import com.mulanweb.db.common.Constant;
import com.mulanweb.db.common.RandomStringGenerator;
import com.mulanweb.db.common.WxParaFormatter;
import com.mulanweb.handler.GetHandler;
import com.mulanweb.handler.wechat.UserHandler;
import com.mulanweb.validator.annotation.ValidateFile;
import com.mulanweb.validator.annotation.ValidateForm;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by Administrator on 2016/9/26.
 */
@ValidateFile
public class EventController extends BaseController {

    //String openId=  getSessionAttr("openId");

    public void route()  throws IOException{
        HttpServletRequest request = super.getRequest();
        HttpServletResponse response = super.getResponse();
        if (StrKit.notBlank(request.getParameter("code"))) {
            String code = request.getParameter("code");
            String para = GetHandler.get(Constant.WeChatFinalValue.getWebAuthorizeAccessToken(code));
            Map<String, String> mapPara = WxParaFormatter.jsonToMap(para);
            if (mapPara.containsKey("errcode")) {
                returnJson(0, "授权出错，请重试");
            } else {
                String state = request.getParameter("state");
                String openId = mapPara.get("openid");//"oULNBwOvt_D2A_8se1bQOQ06ky0w"; //
                super.setSessionAttr("openId", openId);
                if ("t1t".equals(state)) {
                    //创建活动
                    String tag = RandomStringGenerator.getRandomStringByLength(32);
                    super.setSessionAttr("tag",tag);
                    create();
                } else if (state != null && state.startsWith("t2t_")) {
                    // 进入投票页面
                    String targetId = state.split("_")[1];
                    User user = User.dao.findFirst("SELECT * FROM `user` WHERE open_id = ? AND status_id = 1",openId);
                    if ( user != null && UserHandler.userNotNull(openId)) {
                        String tag = RandomStringGenerator.getRandomStringByLength(32);
                        super.setSessionAttr("tag",tag);
                        super.setSessionAttr("targetId",targetId);
                        EventAttend eventAttend = EventAttend.dao.findById(targetId);
                        if(eventAttend !=null && eventAttend.getUserId() == user.getId()){
                            redirect("/event/index.jsp");
                        }else{
                            redirect("/event/tp/index.jsp");
                        }
                    } else {
                        // 返回提示用户未关注
                        redirect("/event/error/not_gz.jsp");
                    }
                } else {
                    //没有权限操作
                    returnJson(0, "授权后未找到关键字");
                }
            }
        }
    }

    // 创建活动
    public synchronized void create() throws IOException{
        String openId = getSessionAttr("openId")+"";
        //搜索活动参与者
        User user = User.dao.findFirst("SELECT * FROM `user` WHERE open_id = ? AND status_id = 1", openId);
        Map<String, Object> map = new HashMap<String, Object>();
        if (user != null) {
            Event event = Event.dao.findFirst("SELECT * FROM event WHERE id =1 AND start_time <= NOW() AND NOW() < end_time");
            //判断活动是否有效
            if (event == null) {
                // 活动已结束,或未开始;
                returnJson(0, "活动已结束,或未开始");
                return;
            }
            EventAttend eventAttend = EventAttend.dao.findFirst("SELECT * FROM event_attend WHERE user_id = ?", user.getId());
            //判断是否参加活动
            if (eventAttend == null) {
                //用户未参加此活动，为用户参加活动，并返回到参加活动页面
                eventAttend = new EventAttend();
                eventAttend.setClickAmount(38);
                eventAttend.setRestClickAmount(38);
                eventAttend.setDisanceRest(8000);
                eventAttend.setDisanceRest(8000);
                eventAttend.setEventId(1);
                eventAttend.setUserId(user.getId());
                eventAttend.setCreateTime(new Date());
                if (eventAttend.save()) {
                    super.setSessionAttr("targetId",eventAttend.getId());
                    redirect("/event/tp/index.jsp");
                   //redirect("/event/index.jsp?dr=" + dr + "&head_img=" + user.getLogoPath() + "&username" + user.getWechatNickname());
                } else {
                    //todo 活动参加失败，重新参加页面
                }
            } else {
                //用户已参加活动，返回到活动页面
                super.setSessionAttr("targetId", eventAttend.getId());
                redirect("/event/index.jsp");
                //redirect("/event/index.jsp?dr=" + dr + "&hi=" + user.getLogoPath());
            }
        } else {
            // 提示用户未关注，返回到带二维码的提示页面
            redirect("/event/error/not_gz.jsp");
        }
    }

    // 创建活动
    public synchronized void create2() throws IOException{
        String openId = getSessionAttr("openId")+"";
        //搜索活动参与者
        User user = User.dao.findFirst("SELECT * FROM `user` WHERE open_id = ? AND status_id = 1", openId);
        if (user != null) {
            Event event = Event.dao.findFirst("SELECT * FROM event WHERE id =1 AND start_time <= NOW() AND NOW() < end_time");
            //判断活动是否有效
            if (event == null) {
                // 活动已结束,或未开始;
                returnJson(0, "活动已结束,或未开始");
                return;
            }
            EventAttend eventAttend = EventAttend.dao.findFirst("SELECT * FROM event_attend WHERE user_id = ?", user.getId());
            //判断是否参加活动
            if (eventAttend == null) {
                //用户未参加此活动，为用户参加活动，并返回到参加活动页面
                eventAttend = new EventAttend();
                eventAttend.setClickAmount(38);
                eventAttend.setRestClickAmount(38);
                eventAttend.setDisanceRest(8000);
                eventAttend.setDisanceRest(8000);
                eventAttend.setEventId(1);
                eventAttend.setUserId(user.getId());
                eventAttend.setCreateTime(new Date());
                if (eventAttend.save()) {
                    super.setSessionAttr("targetId",eventAttend.getId());
                    returnSuccessJson("/event/index.jsp");
                    //redirect("/event/index.jsp?dr=" + dr + "&head_img=" + user.getLogoPath() + "&username" + user.getWechatNickname());
                } else {
                    returnFailureJson();
                }
            } else {
                //用户已参加活动，返回到活动页面
                super.setSessionAttr("targetId", eventAttend.getId());
                returnSuccessJson("/event/index.jsp");
                //redirect("/event/index.jsp?dr=" + dr + "&hi=" + user.getLogoPath());
            }
        } else {
            // 提示用户未关注，返回到带二维码的提示页面
            redirect("/event/error/not_gz.jsp");
        }
    }

    public void exchangeCoupon() {
        String openId = getSessionAttr("openId")+""; //"oULNBwOvt_D2A_8se1bQOQ06ky0w";//
        User user = User.dao.findFirst("SELECT * FROM `user` WHERE open_id = ? AND status_id = 1", openId);
        if (user != null) {
            //判断用户是否中奖
            EventAttend eventAttend = EventAttend.dao.findFirst("SELECT * FROM event_attend WHERE user_id = ?", user.getId());
            if (eventAttend != null
                    && eventAttend.getRestClickAmount() <= 0
                    && eventAttend.getDisanceRest() <= 0) {
                List<EventAttend> eventAttendList = EventAttend.dao.find("SELECT * FROM event_attend WHERE complete_time IS NOT NULL ORDER BY complete_time ");
                int i = 0; //索引号
                for (EventAttend winning : eventAttendList) {
                    if (winning.getId() == eventAttend.getId()) {
                        // 用户中奖
                        if (i == 0) {
                            //用户一等奖
                            returnSuccessJson("恭喜您第一位到达新西兰,获得600元现金券;券码为:"+Constant.Event.COUPON_CODE_1);
                            break;
                        } else if (i == 1) {
                            //用户二等奖
                            returnSuccessJson("恭喜您第二位到达新西兰,获得600元现金券;券码为:"+Constant.Event.COUPON_CODE_2);
                            break;
                        } else if (i == 2) {
                            //用户三等奖
                            returnSuccessJson("恭喜您第三位到达新西兰,获得600元现金券;券码为:"+Constant.Event.COUPON_CODE_3);
                            break;
                        } else {
                            ///未进前三，获得辛苦奖
                            returnSuccessJson("您已到达新西兰,获得满减优惠券(￥600减￥40); 券码为:"+Constant.Event.COUPON_CODE_4);
                            break;
                        }
                    }
                    i++;
                }
            } else {
                returnJson(0, "未满足领取条件");
            }
        } else {
            // 用户不存在，提示用户关注
            redirect("/event/error/not_gz.jsp");
        }
    }

    /**
     * 获取排行榜信息 需要tag
     */
    public void getOrder() {
        //String openId = "oULNBwOvt_D2A_8se1bQOQ06ky0w";//getSessionAttr("openId");

        String targetId = getSessionAttr("targetId")+"";

        String tag = getPara("tag");
        if (tag !=null &&  tag.equals(getSessionAttr("tag"))) {
            EventAttend eventAttend = EventAttend.dao.findById(targetId);
            if (eventAttend == null) {
                returnJson(0, "活动不存在");
                return;
            }
            List<EventSustain> list = EventSustain.dao.find("SELECT * FROM event_sustain WHERE attend_id = ? ORDER BY create_time DESC", eventAttend.getId());
            List<Map> result = new ArrayList<>();
            for(EventSustain es : list){
                Map<String,Object> map = new HashMap<String,Object>();
                User u = User.dao.findById(es.getUserId());
                map.put("username",u.getWechatNickname());
                map.put("headImg",u.getLogoPath());
                map.put("time",es.getCreateTime());
                map.put("juli",es.getValue());
                result.add(map);
            }
            returnSuccessJson(result);
        } else {
            //todo 提示用户未参加活动或未授权
            returnJson(0, "此用户未参加该活动");
        }
    }



    private boolean isActiveUser(User user) {
        return !(null != user && user.getStatusId() == 1);
    }
    private boolean isActiveEvent(EventAttend eventAttend) {
        if (null == eventAttend) {
            return false;
        }
        Event event = Event.dao.findFirst("SELECT * FROM event WHERE id =? AND start_time <= NOW() AND NOW() < end_time", eventAttend.getEventId());
        if (event == null) {
            return false;
        }
        return false;

    }

    protected void renderData(int code, String message) {
        Ret ret = Ret.create("ReturnCode", code);
        if (StrKit.notBlank(message))
        {
            ret.put("AlertMessage", message);
        }
        super.renderJson(ret.getData());
    }

    private static synchronized void update(EventController controller, User user, String eventId) {
        EventAttend eventAttend = EventAttend.dao.findById(eventId);
        if (controller.isActiveEvent(eventAttend)) {
            controller.renderData(0, "活动已结束,或未开始！");
            return;
        }
        EventSustain eventSustain_ = EventSustain.dao.findFirst("SELECT * FROM event_sustain WHERE user_id = ?", user.getId());
        //判断投票者是存在投票次数，投票次数为一
        if (eventSustain_ != null) {
            //提示用户已无投票权
            controller.renderData(0, "每人仅能给一位好友加油哦！送您一张满1000减50优惠券(券码:" + Constant.Event.COUPON_CODE + ")");
            return;
        }

        Map<String, Object> map = new HashMap<String, Object>();
        //剩余点击次数
        int restClickAmount = eventAttend.getRestClickAmount();
        //随机里程数
        Integer value = 0;
        if (restClickAmount == 1) {
            //得出最后里程数，结束投票，更新完成投票时间
            value = eventAttend.getDisanceRest();
        } else if (restClickAmount > 0) {
            //开始 计算 随机里程参与投票
            value = controller.getRandom(eventAttend.getDisanceRest(), eventAttend.getRestClickAmount());
        } else if (restClickAmount < 0) {
            controller.renderData(0, "已超过投票次数，投票无效");
            return;
        } else {
            //投票已完成
            controller.renderData(0, "投票已结束");
            return;
        }
        final int oValue = value;
        EventSustain eventSustain = new EventSustain();
        eventSustain.setUserId(user.getId());
        eventSustain.setAttendId(eventAttend.getId());
        eventSustain.setValue(value);
        eventSustain.setCreateTime(new Date());

        boolean state = Db.tx(()->{
            if(eventSustain.save()) {
                eventAttend.setRestClickAmount(restClickAmount - 1);
                Integer tag = eventAttend.getDisanceRest() - oValue;
                if (tag <= 0) {
                    tag = 0;
                    eventAttend.setCompleteTime(new Date());
                }
                eventAttend.setDisanceRest(tag);
                return eventAttend.update();
            }
            return false;
        });

        if (state) {
            //提示投票成功
            User targetUser = User.dao.findById(eventAttend.getUserId());

            map.put("value", eventSustain.getValue());
            map.put("username", targetUser.getWechatNickname());
            map.put("couponCode", Constant.Event.COUPON_CODE);//安慰奖
            map.put("code", 1);//操作结果代码
            controller.renderJson(map);
        } else {
            controller.renderData(0, "投票失败");
        }
    }

/*
    public synchronized void startVote1() {
        String openId = getSessionAttr("openId")+"";
        String targetId = getSessionAttr("targetId")+"";
        String tag1 = getPara("tag");

      *//*  String openId = "oULNBwEIa_SQz1UX-Mmx9nO03J6I";
        String targetId = "1";
        String tag1 = getPara("tag");*//*

        User user = User.dao.findFirst("SELECT * FROM `user` WHERE open_id = ?", openId);
        if (tag1 !=null && tag1.equals(getSessionAttr("tag")) && user != null) {
            EventAttend eventAttend = EventAttend.dao.findById(targetId);
            //判断被投票者是否参加过此活动
            if (eventAttend != null) {
                Event event = Event.dao.findFirst("SELECT * FROM event WHERE id =? AND start_time <= NOW() AND NOW() < end_time",eventAttend.getEventId());
                //判断活动是否有效
                if (event == null) {
                    returnJson(0, "活动已结束,或未开始！");
                    return;
                }
                EventSustain eventSustain = EventSustain.dao.findFirst("SELECT * FROM event_sustain WHERE user_id = ?", user.getId());
                //判断投票者是存在投票次数，投票次数为一
                if (eventSustain != null) {
                    //提示用户已无投票权
                    returnJson(0, "每人仅能给一位好友加油哦！送您一张满1000减50优惠券(券码:"+Constant.Event.COUPON_CODE+")");
                    return;
                }
                //剩余打击次数
                int restClickAmount = eventAttend.getRestClickAmount();
                //随机里程数
                Integer value = 0;
                if (restClickAmount > 0) {
                    //开始 计算 随机里程参与投票
                    value = getRandom(eventAttend.getDisanceRest(), eventAttend.getRestClickAmount());
                } else if (restClickAmount == 1) {
                    //得出最后里程数，结束投票，更新完成投票时间
                    value = eventAttend.getDisanceRest();
                } else {
                    //投票已完成
                    returnJson(0, "投票已结束！");
                    return;
                }
                eventSustain = new EventSustain();
                eventSustain.setUserId(user.getId());
                eventSustain.setAttendId(eventAttend.getId());
                eventSustain.setValue(value);
                eventSustain.setCreateTime(new Date());
                if (eventSustain.save()) {
                    eventAttend.setRestClickAmount(eventAttend.getRestClickAmount() - 1);
                    Integer tag = eventAttend.getDisanceRest() - value;
                    if (tag <= 0) {
                        tag = 0;
                        eventAttend.setCompleteTime(new Date());
                    }
                    eventAttend.setDisanceRest(tag);
                    eventAttend.update();
                    //提示投票成功
                    User targetUser = User.dao.findById(eventAttend.getUserId());
                    Map<String,Object> map = new HashMap<String,Object>();
                    map.put("value",eventSustain.getValue());
                    map.put("username",targetUser.getWechatNickname());
                    map.put("couponCode",Constant.Event.COUPON_CODE);//安慰奖
                    map.put("ReturnCode",1);//操作结果代码
                    renderJson(map);
                } else {
                    returnJson(0, "投票失败");
                }
            } else {
                //todo 提示错误
                returnJson(0, "投票失败");
            }
        }else{
            returnFailureJson();
        }
    }*/

    /**
     * 开始投票 需要tag
     */
    public void startVote(){

        String openId =getSessionAttr("openId")+"";// getPara("userId");//"oULNBwOvt_D2A_8se1bQOQ06ky0w";//
        String targetId = getSessionAttr("targetId")+"";//"1";//
        String tag1 = getPara("tag");

        if(!(tag1 != null && tag1.equals(getSessionAttr("tag")))){
            renderData(0, "参数错误");
        }
        User user = User.dao.findFirst("SELECT * FROM `user` WHERE open_id = ?",openId);

        if(isActiveUser(user)) {
            renderData(0, "用户不存在或未关注");
            return;
        }
        EventAttend eventAttend = EventAttend.dao.findById(targetId);
        if (isActiveEvent(eventAttend)) {
            renderData(0, "活动已结束,或未开始！");
            return;
        }

        EventSustain eventSustain = EventSustain.dao.findFirst("SELECT * FROM event_sustain WHERE user_id = ?", user.getId());
        //判断投票者是存在投票次数，投票次数为一
        if (eventSustain != null) {
            //提示用户已无投票权
            renderData(0, "每人仅能给一位好友加油哦！送您一张满1000减50优惠券(券码:" + Constant.Event.COUPON_CODE + ")");
            return;
        }

        //剩余点击次数
        int restClickAmount = eventAttend.getRestClickAmount();
        //随机里程数
        Integer value = 0;
        if (restClickAmount > 0) {
            update(this, user, targetId);
        } else {
            //投票已完成
            renderData(0, "投票已结束");
            return;
        }
    }

    /**
     * 投票算法
     * 取 剩余里程数 与 剩余点击次数 商 的平均数，最后随机数的范围为：平均数上下起伏 30%
     * @param disanceRest 剩余里程数
     * @param restClick   剩余点击次数
     * @return 随机的里程数
     */
    private Integer getRandom(Integer disanceRest, Integer restClick) {
        Integer pingJun = disanceRest / restClick;
        Float percent = 0.3F;
        Random random = new Random();
        int max = Math.round(pingJun + pingJun * percent);
        int min = Math.round(pingJun - pingJun * percent);
        System.out.println(max);
        System.out.println(min);
        int value = random.nextInt(max) % (max - min + 1) + min;
        return value;
    }

    /**
     * 得到活动详情 需要Tag
     */
    public void getDetailPage(){
        String tag = getPara("tag");
        //String openId= getSessionAttr("openId");
        //if(tag.equals(getSessionAttr("tag")) && UserHandler.userNotNull(openId)){
        String targetId = getSessionAttr("targetId")+"";
        EventAttend eventAttend = EventAttend.dao.findById(targetId);
        if(tag !=null &&  tag.equals(getSessionAttr("tag")) && eventAttend != null){
            //todo返回详细信息
            User user = User.dao.findById(eventAttend.getUserId());
            if(eventAttend == null || user == null){
                returnFailureJson();
                return;
            }
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("username",user.getWechatNickname());
            map.put("headImg",user.getLogoPath());
            map.put("restD",eventAttend.getDisanceRest());
            renderJson(map);
        }else{
            //todo 返回错误页面
            returnFailureJson();
        }
    }

}
